﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using TournamentDatabase.Objects;
using TournamentDatabase.DialogBoxes.Edit;
using TournamentDatabase.DialogBoxes.Select;
using TournamentDatabase.Database;
using TournamentDatabase.Singletons;

namespace TournamentDatabase.Views
{
	/// <summary>
	/// Interaction logic for TournamentView.xaml
	/// </summary>
	public partial class TournamentView : Window
	{
		Tournament m_tournament;
		Competition m_competitionSelected;
		Organiser m_organiserSelected;
		List<Competition> m_competitionList;
		List<Organiser> m_organiserList;
		string m_competitionSearchText;
		string m_organiserSearchText;

		public string OrganiserSearchText
		{
			get { return m_organiserSearchText; }
			set { m_organiserSearchText = value; }
		}
		public string CompetitionSearchText
		{
			get { return m_competitionSearchText; }
			set { m_competitionSearchText = value; }
		}
		public List<Organiser> OrganiserList
		{
			get { return m_organiserList; }
			set { m_organiserList = value; }
		}
		public List<Competition> CompetitionList
		{
			get { return m_competitionList; }
			set { m_competitionList = value; }
		}
		public Organiser OrganiserSelected
		{
			get { return m_organiserSelected; }
			set { m_organiserSelected = value; }
		}
		public Competition CompetitionSelected
		{
			get { return m_competitionSelected; }
			set { m_competitionSelected = value; }
		}
		public Tournament Tournament
		{
			get { return m_tournament; }
			set { m_tournament = value; }
		}

		public TournamentView(Tournament tournament)
		{
			InitializeComponent();
			m_tournament = tournament;

			this.DataContext = this;
		}

		#region Competition

		private void addCompetitonButton_Click(object sender, RoutedEventArgs e)
		{
			CompetitionEditDialogBox cedb = new CompetitionEditDialogBox(m_tournament);

			cedb.ShowDialog();

			if (cedb.DialogResult.HasValue && cedb.DialogResult.Value)
			{
				CompetitionSearch();
			}
		}

		private void editCompetitionButton_Click(object sender, RoutedEventArgs e)
		{
			if (m_competitionSelected == null)
				return;

			CompetitionView cv = new CompetitionView(m_competitionSelected);

			cv.ShowDialog();

			if (cv.DialogResult.HasValue && cv.DialogResult.Value)
			{
				CompetitionSearch();
			}
		}

		private void deleteCompetitionButton_Click(object sender, RoutedEventArgs e)
		{
			if (m_competitionSelected == null)
				return;

			string messageBoxText = "Do you really want to delete this competition?";
			string caption = "This will delete all associated competiton results.";
			MessageBoxButton btnMessageBox = MessageBoxButton.YesNo;
			MessageBoxImage icnMessageBox = MessageBoxImage.Warning;
			MessageBoxResult rsltMessageBox = MessageBox.Show(messageBoxText, caption, btnMessageBox, icnMessageBox);

			// Process message box results
			if (rsltMessageBox == MessageBoxResult.Yes)
			{
				DatabaseSingleton.GetDatabaseAccessor().DeleteCompetition(m_competitionSelected);

				CompetitionSearch();
			}
		}

		private void OnCompetitionSearch(string searchText)
		{
			m_competitionSearchText = searchText;
			CompetitionSearch();
		}

		private void CompetitionSearch()
		{
			if (m_competitionSearchText == null || m_competitionSearchText.Length == 0)
			{
				string where = "tid = " + m_tournament.TournamentID;
				m_competitionList = DatabaseSingleton.GetDatabaseAccessor().QueryCompetition(where, OrderBy.None, "");
			}
			else
			{
				string where = string.Format("tid = {0} AND type LIKE '%{1}%'", m_tournament.TournamentID, m_competitionSearchText);
				m_competitionList = DatabaseSingleton.GetDatabaseAccessor().QueryCompetition(where, OrderBy.None, "");
			}
		}

		#endregion

		#region Organiser

		private void addOrganiserButton_Click(object sender, RoutedEventArgs e)
		{
			OrganiserSelectDialogBox osdb = new OrganiserSelectDialogBox();

			osdb.ShowDialog();

			if (osdb.DialogResult.HasValue && osdb.DialogResult.Value)
			{
				OrganisesEditDialogBox oedb = new OrganisesEditDialogBox(osdb.SelectedOrganiser, m_tournament);

				if (oedb.DialogResult.HasValue && oedb.DialogResult.Value)
				{
					OrganiserSearch();
				}
			}
		}

		private void deleteOrganiserButton_Click(object sender, RoutedEventArgs e)
		{
			if (m_organiserSelected == null)
				return;

			string messageBoxText = "Do you really want to remove this organiser?";
			string caption = "This will delete the organising information for this organser.";
			MessageBoxButton btnMessageBox = MessageBoxButton.YesNo;
			MessageBoxImage icnMessageBox = MessageBoxImage.Warning;
			MessageBoxResult rsltMessageBox = MessageBox.Show(messageBoxText, caption, btnMessageBox, icnMessageBox);

			// Process message box results
			if (rsltMessageBox == MessageBoxResult.Yes)
			{
				DatabaseSingleton.GetDatabaseAccessor().DeleteOrganiser(m_organiserSelected);

				OrganiserSearch();
			}
		}

		private void OnOrganiserSearch(string searchText)
		{
			m_organiserSearchText = searchText;
			OrganiserSearch();
		}

		private void OrganiserSearch()
		{
			if (m_organiserSearchText == null || m_organiserSearchText.Length == 0)
			{
				string where = "tid = " + m_tournament.TournamentID;
				DatabaseSingleton.GetDatabaseAccessor().QueryOrganises(where, OrderBy.None, "");
			}
			else
			{
				string where = string.Format("tid = {0} AND name LIKE '%{1}%'", m_tournament.TournamentID, m_organiserSearchText);
				DatabaseSingleton.GetDatabaseAccessor().QueryOrganises(where, OrderBy.None, "");
			}
		}

		#endregion

		private void okButton_Click(object sender, RoutedEventArgs e)
		{
			if (!IsValid(this))
				return;

			try
			{
				DatabaseSingleton.GetDatabaseAccessor().UpdateTournament(m_tournament);
			}
			catch
			{
				MessageBox.Show("Error saving to the database!");
				return;
			}

			this.DialogResult = true;
		}

		bool IsValid(DependencyObject node)
		{
			// Check if dependency object was passed
			if (node != null)
			{
				// Check if dependency object is valid.
				// NOTE: Validation.GetHasError works for controls that have validation rules attached 
				bool isValid = !Validation.GetHasError(node);
				if (!isValid)
				{
					// If the dependency object is invalid, and it can receive the focus,
					// set the focus
					if (node is IInputElement) Keyboard.Focus((IInputElement)node);
					return false;
				}
			}

			// If this dependency object is valid, check all child dependency objects
			foreach (object subnode in LogicalTreeHelper.GetChildren(node))
			{
				if (subnode is DependencyObject)
				{
					// If a child dependency object is invalid, return false immediately,
					// otherwise keep checking
					if (IsValid((DependencyObject)subnode) == false) return false;
				}
			}

			// All dependency objects are valid
			return true;
		}
	}
}
